﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilveR.Views.StatsViews;
using System.ComponentModel.DataAnnotations;

namespace SilveR.GUIValidators
{
    public class PowerAnalysisGUIValidator
    {
        private static bool IsNumeric(string value)
        {
            double val;
            return double.TryParse(value, out val);
        }

        public static ValidationResult ValidateGroupMean(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UseSuppliedValues) return ValidationResult.Success;

            if (String.IsNullOrEmpty(variable))
                return new ValidationResult("Group Mean is a required variable");
            else if (!IsNumeric(variable))
                return new ValidationResult("Group Mean is not numeric");
            else
                return ValidationResult.Success;
        }

        public static ValidationResult ValidateStandardDeviation(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UseSuppliedValues || !pav.UseStandardDeviation) return ValidationResult.Success;

            if (String.IsNullOrEmpty(variable))
                return new ValidationResult("Standard Deviation is a required variable");
            else if (!IsNumeric(variable))
                return new ValidationResult("Standard Deviation is not numeric");
            else
                return ValidationResult.Success;
        }

        public static ValidationResult ValidateVariance(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UseSuppliedValues || !pav.UseVariance) return ValidationResult.Success;

            if (String.IsNullOrEmpty(variable))
                return new ValidationResult("Variance is a required variable");
            else if (!IsNumeric(variable))
                return new ValidationResult("Variance entered is not numeric");
            else
                return ValidationResult.Success;
        }

        public static ValidationResult ValidateResponseOrTreatment(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (String.IsNullOrEmpty(variable) && pav.UseDataSetValues)
                return new ValidationResult(context.DisplayName + " is a required variable");
            else
                return ValidationResult.Success;
        }

        public static ValidationResult ValidateControlGroup(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (String.IsNullOrEmpty(variable) && pav.UseDataSetValues && pav.UsePercentChange)
                return new ValidationResult("You have selected % change as expected changes from control, but as you have not defined the control group it is not possible to calculate the % change.");
            else
                return ValidationResult.Success;
        }

        public static ValidationResult ValidateChanges(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if ((context.DisplayName == "Percent Change" && String.IsNullOrEmpty(pav.PercentChange) && pav.UsePercentChange) || (context.DisplayName == "Absolute Change" && String.IsNullOrEmpty(pav.AbsoluteChange) && pav.UseAbsoluteChange))
                return new ValidationResult(context.DisplayName + " is a required variable");
            else
            {
                char[] splitters = { ',' };
                string[] changes = variable.Split(splitters, StringSplitOptions.RemoveEmptyEntries); //split list by comma

                foreach (string s in changes)//go through list and check that is a number and is greater than 0
                {
                    double number;
                    if (!double.TryParse(s, out number))
                    {
                        return new ValidationResult(context.DisplayName + " changes has non-numeric values or the values are not comma separated");
                    }
                    else if (number < 0)
                    {
                        return new ValidationResult(context.DisplayName + " changes has values less than zero");
                    }
                }

                return ValidationResult.Success;
            }
        }

        public static ValidationResult ValidateCustomFrom(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UsePower || !pav.UseCustomPower) return ValidationResult.Success;

            double from;
            bool fromOK = double.TryParse(pav.PowerFrom, out from);

            if (!fromOK)
                return new ValidationResult("Custom from must be a numeric value");
            else
            {
                double to;
                bool toOK = Double.TryParse(pav.PowerTo, out to);

                if (!toOK || from > to)
                {
                    return new ValidationResult("The From value must be less than the To value");
                }

                return ValidationResult.Success;
            }
        }

        public static ValidationResult ValidateCustomTo(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UsePower || !pav.UseCustomPower) return ValidationResult.Success;

            double to;
            bool toOK = double.TryParse(pav.PowerTo, out to);

            if (!toOK)
                return new ValidationResult("Custom to must be a numeric value");
            else
            {
                double from;
                bool fromOK = Double.TryParse(pav.PowerFrom, out from);

                if (!fromOK || from > to)
                {
                    return new ValidationResult("The To value must be greater than the From value");
                }

                return ValidationResult.Success;
            }
        }

        public static ValidationResult ValidateSampleSizeFrom(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UseCustomSampleSize) return ValidationResult.Success;

            double from;
            bool fromOK = double.TryParse(pav.SampleSizeFrom, out from);

            if (!fromOK)
                return new ValidationResult("Sample size from must be a numeric value");
            else
            {
                double to;
                bool toOK = Double.TryParse(pav.SampleSizeTo, out to);

                if (!toOK || from > to)
                {
                    return new ValidationResult("The From value must be less than the To value");
                }

                return ValidationResult.Success;
            }
        }

        public static ValidationResult ValidateSampleSizeTo(string variable, ValidationContext context)
        {
            PowerAnalysisVariables pav = (PowerAnalysisVariables)context.ObjectInstance;

            if (!pav.UseCustomSampleSize) return ValidationResult.Success;

            double to;
            bool toOK = double.TryParse(pav.SampleSizeTo, out to);

            if (!toOK)
                return new ValidationResult("Sample size to must be a numeric value");
            else
            {
                double from;
                bool fromOK = Double.TryParse(pav.SampleSizeFrom, out from);

                if (!fromOK || from > to)
                {
                    return new ValidationResult("The To value must be greater than the From value");
                }

                return ValidationResult.Success;
            }
        }
    }
}
